package jblip.gui.components;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import jblip.gui.Configuration;
import jblip.gui.JBlip;

public class LoginFrame extends JFrame {
  private static final long serialVersionUID = 1L;

  String user = null;

  String pass = null;

  public LoginFrame() {
    super("JBlip");
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.add(new LoginPanel(this));
    this.pack();
    this.setLocationRelativeTo(null);
    this.invalidate();
    this.repaint();
    this.setResizable(false);
    this.setVisible(true);
  }

  public String getPass() {
    return this.pass;
  }

  public String getUser() {
    return this.user;
  }
}

class LoginPanel extends JPanel {
  private static final long serialVersionUID = 1L;

  private static final Dimension PANEL_SIZE;

  private static final Dimension ICON_SIZE;

  private static final Dimension BUTTONS_SIZE;

  private static final Image BLIP_ICON;

  private static class IconPanel extends JPanel {
    private static final long serialVersionUID = 1L;

    @Override
    protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(BLIP_ICON, 0, 0, this);
    }

    @Override
    public Dimension getSize() {
      return ICON_SIZE;
    }

    @Override
    public Dimension getMinimumSize() {
      return ICON_SIZE;
    }
  }

  static {
    PANEL_SIZE = new Dimension(320, 320);
    BUTTONS_SIZE = new Dimension(160, 25);
    ICON_SIZE = new Dimension(320, 227);
    BLIP_ICON =
        Toolkit.getDefaultToolkit().createImage(
            JPanel.class.getResource("/jblip/gui/resources/blip-logo.jpg"));
  }

  private final LoginFrame login_frame;

  public LoginPanel(final LoginFrame frame) {
    super();
    this.login_frame = frame;
    setSize(PANEL_SIZE);
    initLayout();
    setBorder(BorderFactory.createEtchedBorder());
    setVisible(true);
  }

  private void initLayout() {
    final MediaTracker tracker = new MediaTracker(this);
    tracker.addImage(BLIP_ICON, 0, ICON_SIZE.width, ICON_SIZE.height);
    try {
      tracker.waitForID(0);
    } catch (InterruptedException ie) {
      System.err.println(ie);
      System.exit(1);
    }

    final IconPanel iconpanel = new IconPanel();

    final String username = JBlip.instance().getConfiguration().getLogin();
    final String password = JBlip.instance().getConfiguration().getPassword();

    final JTextField field_user = new JTextField(username);
    final JTextField field_pass = new JPasswordField(password);

    final JCheckBox box_store = new JCheckBox("Zapamiętaj hasło");
    box_store.setBackground(this.getBackground());
    box_store.addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(final ChangeEvent e) {
        final Configuration cfg = JBlip.instance().getConfiguration();
        cfg.setStorePassword(box_store.isSelected());
      }
    });
    
    final Component box_sep = Box.createHorizontalGlue();

    final JLabel label_user = new JLabel("Login:");
    final JLabel label_pass = new JLabel("Hasło:");

    final JButton button_login = new JButton("Zaloguj");
    button_login.setPreferredSize(BUTTONS_SIZE);
    button_login.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        try {
          login_frame.user = field_user.getText();
          login_frame.pass = field_pass.getText();
          Thread notify_blip = new Thread(new Runnable() {
            @Override
            public void run() {
              final JBlip jblip_instance = JBlip.instance();
              synchronized (jblip_instance) {
                jblip_instance.notify();
                try {
                  jblip_instance.wait();
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
                if (jblip_instance.getBlipClient() == null) {
                  // JBlip thread sleeps now
                  JOptionPane.showMessageDialog(
                      login_frame, "Can't login, client failed");
                  LoginPanel.this.enableChildren();
                  jblip_instance.getConfiguration().unsetCredentials();
                } else {
                  login_frame.dispose();
                }
              }
            }
          });
          LoginPanel.this.disableChildren();
          notify_blip.start();
        } catch (Exception exc) {
          JOptionPane.showMessageDialog(
              login_frame, "Can't login, exception caught");
          exc.printStackTrace();
        }
      }
    });

    final GroupLayout layout = new GroupLayout(this);
    this.setLayout(layout);

    layout.setAutoCreateGaps(true);
    layout.setAutoCreateContainerGaps(true);

    SequentialGroup ver_layout = layout.createSequentialGroup();
    ver_layout.addComponent(iconpanel);
    ver_layout.addGroup(layout.createBaselineGroup(false, false).addComponent(
        label_user).addComponent(field_user));
    ver_layout.addGroup(layout.createBaselineGroup(false, false).addComponent(
        label_pass).addComponent(field_pass));
    ver_layout.addGroup(layout.createParallelGroup().addComponent(box_store)
        .addComponent(box_sep).addComponent(button_login));

    ParallelGroup hor_layout = layout.createParallelGroup();
    hor_layout.addComponent(iconpanel);
    hor_layout.addGroup(layout.createSequentialGroup().addComponent(label_user)
        .addComponent(field_user));
    hor_layout.addGroup(layout.createSequentialGroup().addComponent(label_pass)
        .addComponent(field_pass));
    hor_layout.addGroup(layout.createSequentialGroup().addComponent(box_store)
        .addComponent(box_sep).addComponent(button_login));

    layout.setHorizontalGroup(hor_layout);
    layout.setVerticalGroup(ver_layout);
  }

  protected void enableChildren() {
    for (Component cmp : getComponents()) {
      cmp.setEnabled(true);
    }
  }

  protected void disableChildren() {
    for (Component cmp : getComponents()) {
      cmp.setEnabled(false);
    }
  }

  @Override
  public Color getBackground() {
    return Color.WHITE;
  }
}